package com.ifcar.app.weibo;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import net.oauth.OAuth;
import net.oauth.OAuth.Parameter;
import net.oauth.OAuthAccessor;
import net.oauth.OAuthException;
import net.oauth.OAuthMessage;
import net.oauth.ParameterStyle;
import net.oauth.http.HttpMessage;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;

import android.util.Log;

/**
 * Utils class for sending request and process response.
 *
 */
public class OAuthHelper {
    public static final String HTTP_STAT = "stat";

    /**
     * GET method to send query string url
     * @param client
     * @param urlWithParam
     * @return
     * @throws IOException
     */
    public static HttpResponse requestGet(HttpClient client, String urlWithParam)
            throws IOException {
        return requestGet(client, urlWithParam, null);
    }

    /**
     * GET method to send url with query string, and header of request
     * @param client
     * @param urlWithParam
     * @param headers
     * @return
     * @throws IOException
     */
    public static HttpResponse requestGet(HttpClient client,
            String urlWithParam, Header[] headers) throws IOException {
        HttpGet httpget = null;
        
        httpget = new HttpGet(urlWithParam);
        HttpParams params = new BasicHttpParams();
        HttpClientParams.setRedirecting(params, false);
        httpget.setParams(params);
        if (headers != null) {
            for (Header header: headers) {
                httpget.addHeader(header);
            }
        }
        httpget.addHeader("Content-Type", "application/atom+xml");
        HttpResponse response = client.execute(httpget);
        
        return response;
    }
    
    public static HttpResponse requestPostUrlEncode(HttpClient client,
            String urlWithParam, OAuthAccessor accessor, Properties oauthProps, Properties postInfo) throws Exception {
    	
        PostEntity entity = new PostEntityUrlEncode(accessor, oauthProps);
        HttpPost httppost = entity.getHttpPost(urlWithParam, postInfo);
        HttpResponse response = client.execute(httppost);

        return response;
    }
    
    
    public static HttpResponse requestPostMultiPart(HttpClient client,
            String urlWithParam, OAuthAccessor accessor, Properties oauthProps, Properties postInfo) throws Exception {
        PostEntity entity = new PostEntityMultiPart(accessor, oauthProps);
        HttpPost httppost = entity.getHttpPost(urlWithParam, postInfo);
        HttpResponse response = client.execute(httppost);

        return response;
    }

    /**
     * generate header by accessor and type(GET, POST), properties, and url.
     * @param accessor
     * @param type
     * @param props
     * @param url
     * @return
     * @throws OAuthException
     * @throws IOException
     * @throws URISyntaxException
     */
    public static Header[] perpareHeader(OAuthAccessor accessor, String type,
            Map<String, String> props, String url) throws OAuthException, IOException,
            URISyntaxException {
        List<Parameter> list = new ArrayList<Parameter>();
        if (props != null) {
            for (Entry<String, String> entry: props.entrySet()) {
                list.add(new Parameter((String) entry.getKey(), (String) entry
                        .getValue()));
            }
        }
        OAuthMessage request = new OAuthMessage(type, url, list);
        request.addRequiredParameters(accessor);
        HttpMessage httpRequest = HttpMessage.newRequest(request,
                ParameterStyle.AUTHORIZATION_HEADER);
        
        List<Header> newHeaders = new ArrayList<Header>();

        for (Entry<String, String> header: httpRequest.headers) {
            newHeaders.add(new BasicHeader(header.getKey(), header.getValue()));
        }
        Header[] headers = new Header[newHeaders.size()];
        return newHeaders.toArray(headers);
    }

    /**
     * generate query url by accessor and type(GET, POST), properties, and url.
     * @param accessor
     * @param type
     * @param props
     * @param url
     * @return
     * @throws OAuthException
     * @throws IOException
     * @throws URISyntaxException
     */
    public static URL perpareQueryString(OAuthAccessor accessor, String type,
            Properties props, String url) throws OAuthException, IOException,
            URISyntaxException {
        List<Parameter> list = new ArrayList<Parameter>();
        for (Entry<Object, Object> entry: props.entrySet()) {
            list.add(new Parameter((String) entry.getKey(), (String) entry
                    .getValue()));
        }
        OAuthMessage request = new OAuthMessage(type, url, list);
        request.addRequiredParameters(accessor);
        HttpMessage httpRequest = HttpMessage.newRequest(request,
                ParameterStyle.QUERY_STRING);

        return httpRequest.url;
    }

    /**
     * process response to a {@link java.util.Properties Properties} object
     * @param response
     * @return
     */
    public static Map<String, String> processResponse(String response) {

    	Map<String, String> p = new HashMap<String, String>();
        String[] params = response.split("&");

        for (String param: params) {
            String[] name2value = param.split("=");
            if (name2value.length != 2) {
                String key = "";
                if (p.get(key) == null) {
                    p.put(key, param);
                } else {
                    p.put(key, p.get(key).concat("||").concat(param));
                }
            } else {
                p.put(name2value[0], name2value[1]);
            }
        }
        return p;
    }

    /**
     * generate query string with properties
     * @param url
     * @param p
     * @return
     * @throws IOException
     */
    public static String generateQueryString(String url, Map<String, String> p)
            throws IOException {
        for (Entry<String, String> entry: p.entrySet()) {
            url = OAuth.addParameters(url, (String) entry.getKey(),
                    (String) entry.getValue());
        }
        return url;
    }
}
